package com.cloudsea.yunhaistores.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cloudsea.yunhaistores.dto.PaymentNotifyDTO;
import com.cloudsea.yunhaistores.entity.OrderItems;
import com.cloudsea.yunhaistores.entity.PaymentOrders;
import com.cloudsea.yunhaistores.mapper.OrderItemsMapper;
import com.cloudsea.yunhaistores.mapper.PaymentOrdersMapper;
import com.cloudsea.yunhaistores.service.PaymentService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Service
public class PaymentServiceImpl implements PaymentService {

    private static final Logger log = LoggerFactory.getLogger(PaymentServiceImpl.class);

    @Autowired
    private PaymentOrdersMapper paymentOrdersMapper;

    // <<<--- 核心改动 1: 注入 OrderItemsMapper 和 StringRedisTemplate ---
    @Autowired
    private OrderItemsMapper orderItemsMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    // <<<--- 核心改动 2: 定义Redis Key的前缀 ---
    private static final String REALTIME_SALES_KEY_PREFIX = "sales:realtime:";

    @Override
    @Transactional // 添加事务注解，保证数据库和Redis操作的一致性
    public boolean handleSuccessfulPayment(PaymentNotifyDTO dto) {
        // 1. 根据订单号查询订单
        QueryWrapper<PaymentOrders> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", dto.getOrderNo());
        PaymentOrders order = paymentOrdersMapper.selectOne(queryWrapper);

        // 2. 校验订单是否存在
        if (order == null) {
            log.warn("接收到不存在的订单号的回调通知: {}", dto.getOrderNo());
            return false;
        }

        // 3. 校验订单状态，保证幂等性
        if (order.getPayStatus() != 0) {
            log.info("订单 {} 已被处理，无需重复执行回调逻辑。", dto.getOrderNo());
            return true;
        }

        // 4. 更新订单状态
        order.setPayStatus(1);
        order.setFulfillmentStatus(1);
        order.setPaidAt(LocalDateTime.now());
        order.setTransactionId(dto.getTransactionId());
        order.setPaymentMethod(dto.getPaymentMethod());
        paymentOrdersMapper.updateById(order);

        // <<<--- 核心改动 3: 更新Redis实时销量计数器 ---
        try {
            // a. 根据订单ID查询该订单的所有商品项
            List<OrderItems> items = orderItemsMapper.selectList(
                    new QueryWrapper<OrderItems>().eq("order_id", order.getId())
            );

            // b. 遍历商品项，更新每个SKU的销量计数
            LocalDate today = LocalDate.now();
            String dateStr = today.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

            for (OrderItems item : items) {
                // 拼接Key, e.g., sales:realtime:19600...:19700...:2024-10-31
                String key = REALTIME_SALES_KEY_PREFIX + order.getStoreId() + ":" + item.getSkuId() + ":" + dateStr;
                // 使用 INCRBY 命令，原子性地增加销量
                redisTemplate.opsForValue().increment(key, item.getQuantity());
            }
            log.info("成功更新订单 [{}] 的Redis实时销量计数。", order.getOrderNo());
        } catch (Exception e) {
            // 重要的异常处理：即使Redis操作失败，也不应该影响主流程（订单状态更新）
            // 我们只记录一个严重的错误日志，以便后续排查
            log.error("更新Redis实时销量计数失败！订单号: {}", order.getOrderNo(), e);
        }

        // TODO:这里可以触发后续的实时业务,发送WebSocket消息给商家端App,调用打印机API
        // 6. 【后续扩展点】在这里可以触发后续的实时业务
        //    - 发送WebSocket消息给商家端App：“您有新的订单，请及时处理！”
        //    - 调用打印机API，将订单信息打印到后厨。
        return true;
    }
}